home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 3 of 3 / CHAPTE20 / READRIFF.C < prev    next >
C/C++ Source or Header  |  1996-04-29  |  10KB  |  356 lines

  1.  
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include "ReadRiff.h"
  5.  
  6.  
  7. #if defined (WIN32)
  8.     #define IS_WIN32 TRUE
  9. #else
  10.     #define IS_WIN32 FALSE
  11. #endif
  12.  
  13. #define IS_NT      IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
  14. #define IS_WIN32S  IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
  15. #define IS_WIN95   (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
  16.  
  17.  
  18. HINSTANCE hInst;   // current instance
  19.  
  20. LPCTSTR lpszAppName = "MyApp";
  21. LPCTSTR lpszTitle   = "My Application"; 
  22.  
  23. // the rest of the stuff
  24. //......................
  25.  
  26. BOOL RegisterWin95( CONST WNDCLASS* lpwc );
  27.  
  28.  
  29. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  30.                       LPTSTR lpCmdLine, int nCmdShow)
  31. {
  32.    MSG      msg;
  33.    HWND     hWnd; 
  34.    WNDCLASS wc;
  35.  
  36.    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  37.    wc.lpfnWndProc   = (WNDPROC)WndProc;       
  38.    wc.cbClsExtra    = 0;                      
  39.    wc.cbWndExtra    = 0;                      
  40.    wc.hInstance     = hInstance;              
  41.    wc.hIcon         = LoadIcon (hInstance, lpszAppName); 
  42.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  43.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  44.    wc.lpszMenuName  = lpszAppName;              
  45.    wc.lpszClassName = lpszAppName;              
  46.  
  47.    if ( IS_WIN95 )
  48.    {
  49.       if ( !RegisterWin95( &wc ) )
  50.          return( FALSE );
  51.    }
  52.    else if ( !RegisterClass( &wc ) )
  53.       return( FALSE );
  54.  
  55.    hInst = hInstance; 
  56.  
  57.    hWnd = CreateWindow( lpszAppName, 
  58.                         lpszTitle,    
  59.                         WS_OVERLAPPEDWINDOW, 
  60.                         CW_USEDEFAULT, 0, 
  61.                         CW_USEDEFAULT, 0,  
  62.                         NULL,              
  63.                         NULL,              
  64.                         hInstance,         
  65.                         NULL               
  66.                       );
  67.  
  68.    if ( !hWnd ) 
  69.       return( FALSE );
  70.  
  71.    ShowWindow( hWnd, nCmdShow ); 
  72.    UpdateWindow( hWnd );         
  73.  
  74.    while( GetMessage( &msg, NULL, 0, 0) )   
  75.    {
  76.       TranslateMessage( &msg ); 
  77.       DispatchMessage( &msg );  
  78.    }
  79.  
  80.    return( msg.wParam ); 
  81. }
  82.  
  83.  
  84. BOOL RegisterWin95( CONST WNDCLASS* lpwc )
  85. {
  86.     WNDCLASSEX wcex;
  87.  
  88.    wcex.style         = lpwc->style;
  89.    wcex.lpfnWndProc   = lpwc->lpfnWndProc;
  90.    wcex.cbClsExtra    = lpwc->cbClsExtra;
  91.    wcex.cbWndExtra    = lpwc->cbWndExtra;
  92.    wcex.hInstance     = lpwc->hInstance;
  93.    wcex.hIcon         = lpwc->hIcon;
  94.    wcex.hCursor       = lpwc->hCursor;
  95.    wcex.hbrBackground = lpwc->hbrBackground;
  96.    wcex.lpszMenuName  = lpwc->lpszMenuName;
  97.    wcex.lpszClassName = lpwc->lpszClassName;
  98.  
  99.    // Added elements for Windows 95.
  100.    //...............................
  101.    wcex.cbSize = sizeof(WNDCLASSEX);
  102.    wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName, 
  103.                             IMAGE_ICON, 16, 16,
  104.                             LR_DEFAULTCOLOR );
  105.             
  106.    return RegisterClassEx( &wcex );
  107. }
  108.  
  109.  
  110.  
  111.  
  112. #define MSG_LEN          1024
  113.  
  114. char       msg[MSG_LEN+1];
  115.  
  116. VOID ReadRiff();
  117. VOID PlayWave(LPSTR pFmt, LPSTR pData, LONG nDataSize);
  118.  
  119.  
  120. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  121. {
  122.    switch( uMsg )
  123.    {
  124.       case WM_COMMAND :
  125.               switch( LOWORD( wParam ) )
  126.               {
  127.                  case IDM_TEST:
  128.                         ReadRiff();
  129.                         break;
  130.  
  131.                  case IDM_ABOUT :
  132.                         DialogBox( hInst, "AboutBox", hWnd, About );
  133.                         break;
  134.  
  135.                  case IDM_EXIT :
  136.                         DestroyWindow( hWnd );
  137.                         break;
  138.               }
  139.               break;
  140.  
  141.       case WM_DESTROY :
  142.               PostQuitMessage(0);
  143.               break;
  144.  
  145.       default :
  146.             return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
  147.    }
  148.  
  149.    return( 0L );               
  150. }
  151.  
  152.  
  153. VOID ReadRiff() 
  154.     HMMIO       hmmio;              // file handle for open file 
  155.     MMCKINFO    ciParentChunk;     // parent chunk information 
  156.     MMCKINFO    ciSubChunk;        // subchunk information structure 
  157.     LONG        nFmtSize;         // size of "FMT" chunk 
  158.     LONG        nDataSize;        // size of "DATA" chunk 
  159.     LPSTR       pFmt;          // address of "FMT" chunk 
  160.     LPSTR       pData;            // address of "DATA" chunk 
  161.  
  162.     // open the wave file using an internal I/O buffer
  163.     //................................................ 
  164.  
  165.     hmmio = mmioOpen("Sample2.wav", NULL, MMIO_READ | MMIO_ALLOCBUF);
  166.  
  167.     if(!hmmio) 
  168.     { 
  169.         MessageBox(NULL, "Failed to open file.", NULL, MB_OK); 
  170.         return; 
  171.     } 
  172.  
  173.     // locate the WAVE chunk within the RIFF chunk
  174.     //............................................
  175.  
  176.     mmioSeek(hmmio, 0, SEEK_SET    ); // reset to beginning of file.
  177.  
  178.     ciParentChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  179.  
  180.     if (mmioDescend(hmmio, (LPMMCKINFO) &ciParentChunk, NULL, MMIO_FINDRIFF)) 
  181.     { 
  182.         MessageBox(NULL, "Not a waveform-audio file.", NULL, MB_OK); 
  183.         mmioClose(hmmio, 0); 
  184.         return; 
  185.     }
  186.     
  187.     // every waveform audio containes a 'fmt' and 'data' chunk,
  188.     // let's get the fmt chunk
  189.     //.........................................................
  190.      
  191.     ciSubChunk.ckid = mmioFOURCC('f', 'm', 't', ' '); 
  192.  
  193.     if (mmioDescend(hmmio, &ciSubChunk, &ciParentChunk, MMIO_FINDCHUNK)) 
  194.     { 
  195.         MessageBox(NULL, "Unable to locate 'fmt' chunk.", NULL, MB_OK);
  196.         mmioClose(hmmio, 0); 
  197.         return; 
  198.     } 
  199.  
  200.     // allocate a buffer to hold the 'fmt' chunk
  201.     //..........................................
  202.  
  203.     nFmtSize = ciSubChunk.cksize; 
  204.  
  205.     pFmt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nFmtSize);
  206.     
  207.     // read the 'fmt' chunk
  208.     //.....................
  209.  
  210.     if (mmioRead(hmmio, (HPSTR)pFmt, nFmtSize) != nFmtSize)
  211.     { 
  212.         MessageBox(NULL, "Error reading 'fmt' chunk.", NULL, MB_OK);
  213.         HeapFree(GetProcessHeap(), 0, pFmt);
  214.         mmioClose(hmmio, 0); 
  215.         return; 
  216.     } 
  217.  
  218.     // ascend out of the 'fmt' subchunk
  219.     //.................................
  220.  
  221.     mmioAscend(hmmio, &ciSubChunk, 0); 
  222.  
  223.     // descend into the 'data' chunk
  224.     //..............................
  225.  
  226.     ciSubChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); 
  227.  
  228.     if (mmioDescend(hmmio, &ciSubChunk, &ciParentChunk, MMIO_FINDCHUNK)) 
  229.     { 
  230.         MessageBox(NULL, "Unable to locate 'data' chunk.", NULL, MB_OK);
  231.         HeapFree(GetProcessHeap(), 0, pFmt); 
  232.         mmioClose(hmmio, 0);  
  233.         return; 
  234.     } 
  235.  
  236.     // allocate a buffer to hold the 'data' chunk
  237.     //...........................................
  238.  
  239.     nDataSize = ciSubChunk.cksize; 
  240.     pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nDataSize);
  241.     
  242.  
  243.     // Read the 'data' chunk
  244.     //......................
  245.  
  246.     if(mmioRead(hmmio, (HPSTR)pData, nDataSize) != nDataSize)
  247.     { 
  248.         MessageBox(NULL, "Error reading 'data' chunk.", NULL, MB_OK);
  249.         HeapFree(GetProcessHeap(), 0, pFmt);
  250.         HeapFree(GetProcessHeap(), 0, pData);
  251.         mmioClose(hmmio, 0); 
  252.         return; 
  253.     } 
  254.  
  255.     // Close the RIFF file
  256.     //....................
  257.  
  258.     mmioClose(hmmio, 0); 
  259.  
  260.     // play the waveform-audio
  261.     //........................
  262.  
  263.     PlayWave(pFmt, pData, nDataSize);
  264.     
  265.     // free 'fmt' and 'data' buffers
  266.     //..............................
  267.     
  268.     HeapFree(GetProcessHeap(), 0, pFmt);
  269.     HeapFree(GetProcessHeap(), 0, pData); 
  270. }
  271.  
  272.  
  273. VOID PlayWave(LPSTR pFmt, LPSTR pData, LONG nDataSize)
  274. {
  275.     // for more information on the usage of the
  276.     // waveOutOpen(), waveOutPrepareHeader(), waveOutWrite(),
  277.     // waveOutUnprepareHeader(), and waveOutClose() functions
  278.     // used in this example, see the chapter on waveform-audio 
  279.     //........................................................
  280.  
  281.     HWAVEOUT    hwo; 
  282.     LPWAVEHDR   pWaveHdr; 
  283.     MMRESULT    rc;
  284.  
  285.     // open waveform-audio driver
  286.     //...........................
  287.  
  288.     rc = waveOutOpen(&hwo, 0, (LPWAVEFORMATEX)pFmt, (DWORD)NULL, 0L, 
  289.                      WAVE_ALLOWSYNC);
  290.     
  291.     if (rc != MMSYSERR_NOERROR)
  292.     {
  293.         MessageBox(NULL, "Unable to open waveform-audio driver.", NULL, MB_OK);
  294.         return;
  295.     }
  296.  
  297.     // allocate and configure WAVEHDR
  298.     //...............................
  299.  
  300.     pWaveHdr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WAVEHDR)); 
  301.      
  302.     if (!pWaveHdr)
  303.     {
  304.         MessageBox(NULL, "Unable to allocate WAVEHDR.", NULL, MB_OK);
  305.         return;
  306.     }
  307.  
  308.     pWaveHdr->lpData = pData; 
  309.     pWaveHdr->dwBufferLength = nDataSize; 
  310.     pWaveHdr->dwFlags = 0L; 
  311.     pWaveHdr->dwLoops = 0L;
  312.     
  313.     // prepare, write, and unprepre WAVEHDR
  314.     //.....................................
  315.     
  316.     waveOutPrepareHeader(hwo, pWaveHdr, sizeof(WAVEHDR)); 
  317.     waveOutWrite(hwo, pWaveHdr, sizeof(WAVEHDR));
  318.     waveOutUnprepareHeader(hwo, pWaveHdr, sizeof(WAVEHDR)); 
  319.  
  320.     // free WAVEHDR buffer and close waveform output device
  321.     //.....................................................
  322.  
  323.     HeapFree(GetProcessHeap(), 0, pWaveHdr);
  324.     waveOutClose(hwo);
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331. LRESULT CALLBACK About( HWND hDlg,           
  332.                         UINT message,        
  333.                         WPARAM wParam,       
  334.                         LPARAM lParam)
  335. {
  336.    switch (message) 
  337.    {
  338.        case WM_INITDIALOG: 
  339.                return (TRUE);
  340.  
  341.        case WM_COMMAND:                              
  342.                if (   LOWORD(wParam) == IDOK         
  343.                    || LOWORD(wParam) == IDCANCEL)    
  344.                {
  345.                        EndDialog(hDlg, TRUE);        
  346.                        return (TRUE);
  347.                }
  348.                break;
  349.    }
  350.  
  351.    return (FALSE); 
  352. }
  353.  
  354.